﻿using System;
using System.Xml;
using System.Xml.Linq;

namespace MockingBird.Simulator.Framework
{
    using Common.Infrastructure.Helpers;
    using Common.Infrastructure.Logging;
    using Interfaces;

    public class SoapFaultBuilder : ISoapFaultBuilder
    {

        private ILogger logger;

        #region "constructor(s)"
        public SoapFaultBuilder(ILogger logger)
        {
            this.logger = logger;
        }

        #endregion

        /// <summary>
        /// Builds a Soap fault from the provided data
        /// </summary>
        /// <param name="responseFile">file containing the xml text of the body</param>
        /// <returns>XmlDocument representing the full soap fault</returns>
        public XmlDocument BuildSoapFault(string responseFile)
        {
            XmlDocument responseData = new XmlDocument();
            responseData.Load(responseFile);
            return BuildSoapFault(responseData);
        }


        /// <summary>
        /// Builds a soap fault from the provided data 
        /// </summary>
        /// <param name="responseData">XmlDocument containing the response data</param>
        /// <returns>XmlDocument representing the full soap fault</returns>
        public XmlDocument BuildSoapFault(XmlDocument responseData)
        {
            //The only unique thing here is the inner text of the file
            return ConstructSoapFaultEnvelope(responseData.InnerText);

        }


        /// <summary>
        /// Builds a soap fault from an exception
        /// </summary>
        /// <param name="e">Exception that acts a source for the fault info</param>
        /// <returns>XmlDocument representing the full soap fault</returns>
        public XmlDocument BuildSoapFault(Exception e)
        {
            //extract the message 
            string message = e.ToString();
            if (e.InnerException != null)
            {
                message = message + "Inner Exception Message : " + e.InnerException.Message;
            }

            //if (!String.IsNullOrEmpty(e.StackTrace))
            //{
            //    message = message + "Stack Trace : " + e.StackTrace;
            //}

            return ConstructSoapFaultEnvelope(message);



        }

        private XmlDocument ConstructSoapFaultEnvelope(string faultDescription)
        {
            //Setup the namespaces
            XNamespace env = XNamespace.Get("http://schemas.xmlsoap.org/soap/envelope/");

            //Working backwards, first setup the soapFault element and fill it up. 
            //Then associate it with a Body element,  then associate that with a root element
            //finally put them into an XDocument and write that out

            XElement faultString = new XElement(env + "FaultString", faultDescription);
            XElement soapFault = new XElement(env + "Fault");
            soapFault.Add(faultString);
            //Setup the body to be prefixed with the main namespace but no other attributes are needed
            XElement body = new XElement(env + "Body");
            body.Add(soapFault);
            //Setup the envelope with the namespaces
            XElement envelope = new XElement(env + "Envelope");
            envelope.Add(body);
            XDocument doc = new XDocument();
            doc.Add(envelope);

            //string s = Path.GetTempFileName();
            //doc.Save(s);

            return XmlHelper.GetXmlDocFromXDoc(doc);


        }

    }
}
